package com.ac.scum.log.task.face.log.counsumer.stages.gamplay;

import com.ac.common.core.id.SnowflakeIdGenerator;
import com.ac.scum.log.bean.Player;
import com.ac.scum.log.bean.PlayerAlarm;
import com.ac.scum.log.bean.ServerFTPLogTrap;
import com.ac.scum.log.task.face.log.counsumer.LogConsumer;
import com.ac.scum.log.task.face.log.counsumer.PlayerAlarmInterface;
import com.ac.scum.log.task.face.log.counsumer.stages.GameplayLogConsumer;
import com.ac.scum.log.task.mapper.log.ServerFTPLogTrapMapper;
import com.ac.scum.log.task.utils.map.GameMapZoneUtil;
import com.ac.scum.log.task.utils.queue.FTPQueueItem;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@AllArgsConstructor
public class TrapConsumer implements PlayerAlarmInterface {
    private final GameMapZoneUtil gameMapZoneUtil;
    private final SnowflakeIdGenerator snowflakeIdGenerator;
    private final ServerFTPLogTrapMapper serverFTPLogTrapMapper;

    public void trapConsumer(List<LogConsumer.GameLogLine> lines, FTPQueueItem ftpQueueItem, GameplayLogConsumer gameplayLogConsumer) {
        try {
            Pattern pattern = Pattern.compile("([\\d.:-]+): \\[([\\w]+)] ([\\w]+)\\. User: ([^\\(]+) \\((\\d+), (\\d+)\\)\\." + " Trap name: ([^\\.]+)\\." + "( Owner: ([^\\(]+) \\((\\d+), (\\d+)\\)\\.)?" + " Location: X=([-\\d.]+) Y=([-\\d.]+) Z=([-\\d.]+)");

            List<ServerFTPLogTrap> traps = Lists.newArrayList();
            for (LogConsumer.GameLogLine line : lines) {
                String lineContext = line.getLineContext();
                Matcher matcher = pattern.matcher(lineContext);
                if (matcher.find()) {
                    String ownerInfo = matcher.group(8);
                    ServerFTPLogTrap logTrap = new ServerFTPLogTrap();
                    logTrap.setId(snowflakeIdGenerator.nextId());
                    logTrap.setFileId(ftpQueueItem.getFileId());
                    logTrap.setServerId(ftpQueueItem.getServer().getId());
                    logTrap.setLineStart(line.getStartByte());
                    logTrap.setLineEnd(line.getEndByte());
                    logTrap.setCreateTime(LocalDateTime.now());

                    logTrap.setServerTime(gameplayLogConsumer.parseTimestamp(matcher.group(1), ftpQueueItem));
                    logTrap.setAction(getTrapAction(matcher.group(3)));
                    logTrap.setPlayerSteamId(Long.parseLong(matcher.group(6)));
                    Player player = gameplayLogConsumer.getOrInsertPlayerServer(logTrap.getPlayerSteamId(), logTrap.getServerId(), matcher.group(4).trim());
                    logTrap.setPlayerId(player.getId());
                    logTrap.setTarget(matcher.group(7));
                    if (ownerInfo != null) {
                        logTrap.setOwnerPlayerSteamId(Long.parseLong(matcher.group(11)));
                        Player ownerPlayer = gameplayLogConsumer.getOrInsertPlayerServer(logTrap.getOwnerPlayerSteamId(), logTrap.getServerId(), matcher.group(9).trim());
                        logTrap.setOwnerPlayerId(ownerPlayer.getId());
                    }
                    logTrap.setLocation(matcher.group(12) + "," + matcher.group(13) + "," + matcher.group(14));
                    logTrap.setLocationZone(gameMapZoneUtil.getZone(Double.parseDouble(matcher.group(12)), Double.parseDouble(matcher.group(13))));
                    String cnTarget = gameplayLogConsumer.getSpawnItemCodeCnName(logTrap.getTarget().replace(" ", "_").toLowerCase());
                    if (!cnTarget.isBlank()) {
                        logTrap.setTarget(cnTarget);
                    }

                    traps.add(logTrap);
                } else {
                    gameplayLogConsumer.commitDiscardLog(ftpQueueItem, line, "trap no match");
                }
            }
            traps.forEach(serverFTPLogTrapMapper::insert);

            List<PlayerAlarm> alarms = Lists.newArrayList();
            if (getCurrentAlarmConfig(ftpQueueItem).getTrapEnabled()) {
                List<Long> hasAlarmPackagePlayerIds = getHasAlarmPackagePlayerIds(ftpQueueItem);
                if (!hasAlarmPackagePlayerIds.isEmpty()) {
                    traps.stream().filter(item -> hasAlarmPackagePlayerIds.contains(item.getOwnerPlayerId()) && (item.getAction() == 3 || item.getAction() == 4)).forEach(item -> {
                        PlayerAlarm playerAlarm = new PlayerAlarm();
                        playerAlarm.setServerId(item.getServerId());
                        playerAlarm.setPlayerId(item.getOwnerPlayerId());
                        playerAlarm.setDetail("lock table");
                        playerAlarm.setLogId(item.getId());
                        playerAlarm.setLogTime(item.getServerTime());
                        playerAlarm.setServerName(ftpQueueItem.getServer().getName());
                        playerAlarm.setAlarmDetail("已被" + (item.getAction() == 3 ? "拆除" : "触发"));
                        playerAlarm.setAlarmItem(item.getLocationZone() + "-" + item.getTarget());
                        alarms.add(playerAlarm);
                    });
                }
            }
            commitAlarmTask(alarms);
        } catch (Exception e) {
            log.error("陷阱日志出现异常", e);
        }
    }

    public Integer getTrapAction(String action) {
        return switch (action) {
            case "Crafted" -> 1;
            case "Armed" -> 2;
            case "Disarmed" -> 3;
            case "Triggered" -> 4;
            default -> 9;
        };
    }
}
